package example

import (
	"context"
	"testing"
	"time"

	"gitee.com/youkelike/rpc/proto/gen"
)

// **************
// 客户示例--服务模板定义
// **************
type UserService struct {
	// 这个类型是函数的字段，可以通过反射来修改
	// 为了简化，有这样两个约定
	// 参数约定：只有两个参数，第一个参数是 context，第二个参数是 struct
	// 返回值约定：只有两个返回值，第一个是 struct，第二个是 error
	GetById      func(ctx context.Context, req *GetByIdReq) (*GetByIdResp, error)
	GetByIdProto func(ctx context.Context, req *gen.GetByIdReq) (*gen.GetByIdResp, error)
}

func (u UserService) Name() string {
	return "user-service"
}

type GetByIdReq struct {
	Id int
}

type GetByIdResp struct {
	Msg string
}

// **************
// 服务示例--的具体服务实现
// **************
type UserServiceServer struct {
	Err error
	Msg string
}

func (u *UserServiceServer) Name() string {
	return "user-service"
}

func (u *UserServiceServer) GetById(ctx context.Context, req *GetByIdReq) (*GetByIdResp, error) {
	return &GetByIdResp{
		Msg: u.Msg,
	}, u.Err
}

func (u *UserServiceServer) GetByIdProto(ctx context.Context, req *gen.GetByIdReq) (*gen.GetByIdResp, error) {
	return &gen.GetByIdResp{
		User: &gen.User{
			Name: u.Msg,
		},
	}, u.Err
}

type UserServiceServerTimeout struct {
	// 为了方便测试加入这个字段
	t     *testing.T
	sleep time.Duration
	Err   error
	Msg   string
}

func (u *UserServiceServerTimeout) Name() string {
	return "user-service"
}

func (u *UserServiceServerTimeout) GetById(ctx context.Context, req *GetByIdReq) (*GetByIdResp, error) {
	if _, ok := ctx.Deadline(); !ok {
		u.t.Fatal("必须设置超时时间")
	}
	time.Sleep(u.sleep)
	return &GetByIdResp{
		Msg: u.Msg,
	}, u.Err
}
